現代的 app,基本都會有和網路進行溝通的 feature。現在想加上一頁 WebView,去連到葛麗絲.霍普的 wiki 頁面。把他連到 wiki 頁面,就可以保證大家在讀資料的時候,資訊是和 wiki 上的一樣,而不用在每次資訊有更新的時候,需要進行 client 端的更新
葛麗絲.霍普 wiki
https://en.wikipedia.org/wiki/Grace_Hopper
目前 SwiftUI 沒有 WebView 元件,所以需要使用 WebKit 的 WKWebView。橋接 SwiftUI 和 UIKit 的方法很簡單,讓元件 conform UIViewRepresentable 後,實作 makeUIView(:), updateUIView(:,:)。就能使用 UIKit 的元件了。
在這個 WKWebViewContainer 裡面,我們會放一個 url: URL,讓裡面的 WKWebView,去讀這個 URLRequest。
/// 記得在這個檔案的上方 import WebKit
struct WKWebViewContainer: UIViewRepresentable {
var url: URL
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ webView: WKWebView, context: Context) {
let request = URLRequest(url: url)
webView.load(request)
}
}
再把 WKWebViewContainer 包起來,這樣可以在上下左右加上其他 SwiftUI 元件。
struct BCWebView: View {
let urlString: String
var body: some View {
if let url = URL(string: urlString) {
WKWebViewContainer(url: url)
} else {
Text("Hello, World!")
}
}
}
嗯…????? 如果解不開,目前的程式碼是會呈現一個 “Hello, world!”,這樣有點怪怪,這邊加上一個 Error View 好了。
在 Image 上,可以直接使用 SF Symbole 的 wifi.exclamationmark,不用特別去找素材。
SF Symbols 的網站,這邊可以下載 SF Symbols 的 app。
https://developer.apple.com/sf-symbols/
// 如果 URLString 給錯,就會跳 Error view
struct URLNotCorrectView: View {
var body: some View {
VStack {
Image(systemName: "wifi.exclamationmark")
.font(.system(size: 150))
.padding()
Text("Oops! Internet got error")
.bold()
.multilineTextAlignment(.center)
.font(.system(size: 44))
}
}
}
最後, BCWebView 看起來就像這樣
struct BCWebView: View {
let urlString: String
var body: some View {
if let url = URL(string: urlString) {
WKWebViewContainer(url: url)
} else {
URLNotCorrectView()
}
}
}
不過, preview 是沒辦法看到網頁的,所以我們在進入點,把 View 換成 BCWebView,看一下結果。
import SwiftUI
@main
struct DemoBackwardsClockApp: App {
var body: some Scene {
WindowGroup {
BCWebView(urlString: "https://en.wikipedia.org/wiki/Grace_Hopper")
// ClockContainerView()
}
}
}
你也可以故意塞一個不是 url 的 string,當無法轉換成 URL,就會出現前面寫好的網路故障 View。